﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LevelEditor.Document;
using System.Xml.Serialization;
using System.Xml;

namespace LevelEditor.Forms
{
    public partial class TileDefinitionsDialog : Form
    {
        #region Fields

        Rectangle destination;

        #endregion

        #region Properties

        public TileSet TileSet { get; set; }

        #endregion

        #region Constructors
        
        public TileDefinitionsDialog()
        {
            InitializeComponent();
        }

        public TileDefinitionsDialog(TileSet tileSet)
        {
            InitializeComponent();
            if (tileSet != null)
            {
                TileSet = new TileSet(tileSet);
                ResetControls();
                LoadData();
            }
        }
        
        #endregion

        #region Interface

        public void ResetControls()
        {
            if (TileSet != null)
            {
                destination = TileSet.GetSourceRectangleForTileValue(0);
                leftFloorNUD.Maximum = destination.Height - 1;
                rightFloorNUD.Maximum = leftFloorNUD.Maximum;
                if (destination.Width < tileDCC.MinimumSize.Width)
                    destination.Width = tileDCC.MinimumSize.Width;
                if (destination.Height < tileDCC.MinimumSize.Height)
                    destination.Height = tileDCC.MinimumSize.Height;
                tileDCC.Size = destination.Size;
                tileNUD.Maximum = TileSet.TileDefinitions.Count - 1;
            }
        }

        public void LoadData()
        {
            if (TileSet != null)
            {
                TileDefinition td = TileSet.TileDefinitions[Convert.ToInt32(tileNUD.Value)];
                obstacleCBox.Checked = td.Obstacle;
                platformCBox.Checked = td.Platform;
                leftFloorNUD.Value = td.LeftFloor;
                rightFloorNUD.Value = td.RightFloor;
                damageNUD.Value = td.Damage;
            }
        }

        #endregion

        private void tileDCC_Paint(object sender, PaintEventArgs e)
        {
            //todo: paint the current tile
            Graphics g = e.Graphics;
            g.Clear(BackColor);
            if (TileSet != null)
            {
                if (TileSet.Image == null && (TileSet.ImageFileName != null || TileSet.ImageFileName != ""))
                    TileSet.LoadImage();
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
                g.DrawImage(TileSet.Image, destination, TileSet.GetSourceRectangleForTileValue(Convert.ToUInt32(tileNUD.Value)), GraphicsUnit.Pixel);
            }
        }

        private void tileNUD_ValueChanged(object sender, EventArgs e)
        {
            LoadData();
            tileDCC.Invalidate();
        }

        private void saveAsBtn_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.DefaultExt = "xml";
            sfd.Filter = "XML Level File (*.xml)|*.xml|All Files (*.*)|*.*";
            DialogResult dr = sfd.ShowDialog(this);
            if (dr == DialogResult.OK)
            {
                try
                {
                    XmlWriter writer = XmlWriter.Create(sfd.FileName);
                    XmlSerializer serializer = new XmlSerializer(typeof(TileSet));
                    serializer.Serialize(writer, TileSet);
                    writer.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, ex.Message, "Invalid File", MessageBoxButtons.OK);
                }
            }
            sfd.Dispose();
        }

        private void loadBtn_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.DefaultExt = "xml";
            ofd.Filter = "XML Level File (*.xml)|*.xml|All Files (*.*)|*.*";
            DialogResult dr = ofd.ShowDialog(this);
            if (dr == DialogResult.OK)
            {
                try
                {
                    XmlReader reader = XmlReader.Create(ofd.FileName);
                    XmlSerializer serializer = new XmlSerializer(typeof(TileSet));
                    TileSet = (serializer.Deserialize(reader) as TileSet);
                    reader.Close();
                    ResetControls();
                    LoadData();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, ex.Message, "Invalid File", MessageBoxButtons.OK);
                }
            }
            ofd.Dispose();
        }

        private void obstacleCBox_CheckedChanged(object sender, EventArgs e)
        {
            TileDefinition td = TileSet.TileDefinitions[Convert.ToInt32(tileNUD.Value)];
            td.Obstacle = obstacleCBox.Checked;
        }

        private void platformCBox_CheckedChanged(object sender, EventArgs e)
        {
            TileDefinition td = TileSet.TileDefinitions[Convert.ToInt32(tileNUD.Value)];
            td.Platform = platformCBox.Checked;
        }

        private void damageNUD_ValueChanged(object sender, EventArgs e)
        {
            TileDefinition td = TileSet.TileDefinitions[Convert.ToInt32(tileNUD.Value)];
            td.Damage = Convert.ToInt32(damageNUD.Value);
        }

        private void leftFloorNUD_ValueChanged(object sender, EventArgs e)
        {
            TileDefinition td = TileSet.TileDefinitions[Convert.ToInt32(tileNUD.Value)];
            td.LeftFloor = Convert.ToUInt32(leftFloorNUD.Value);
        }

        private void rightFloorNUD_ValueChanged(object sender, EventArgs e)
        {
            TileDefinition td = TileSet.TileDefinitions[Convert.ToInt32(tileNUD.Value)];
            td.RightFloor = Convert.ToUInt32(rightFloorNUD.Value);
        }
    }
}
